package cn.swust.designpatternlearningplatform.controller;

import cn.swust.designpatternlearningplatform.common.AnnotationUtils.Authentication;
import cn.swust.designpatternlearningplatform.common.Result.R;
import cn.swust.designpatternlearningplatform.common.utils.AuthUserContext;
import cn.swust.designpatternlearningplatform.common.utils.WordUtils;
import cn.swust.designpatternlearningplatform.domain.dto.ShowStudentDto;
import cn.swust.designpatternlearningplatform.domain.dto.StudentPersonalTrainingResultDto;
import cn.swust.designpatternlearningplatform.domain.dto.TeacherPaperListDto;
import cn.swust.designpatternlearningplatform.domain.dto.TestPaperDto;
import cn.swust.designpatternlearningplatform.domain.enums.RoleEnum;
import cn.swust.designpatternlearningplatform.domain.vo.StudentProblemSolvingSituationVo;
import cn.swust.designpatternlearningplatform.domain.vo.TestPaperVo;
import cn.swust.designpatternlearningplatform.domain.vo.UpdateTestPaperTopic;

import cn.swust.designpatternlearningplatform.service.StudentService;
import cn.swust.designpatternlearningplatform.service.StudentTrainingPaperService;
import cn.swust.designpatternlearningplatform.service.TeacherTestService;
import cn.swust.designpatternlearningplatform.service.TestPaperExportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
@Slf4j
@RequestMapping("/teacherTest")
@Authentication(RoleEnum.TEACHER)
public class TeacherTestController {
    @Value("${file_path}")
    private String filePath;
    @Resource
    private TeacherTestService teacherTestService;
    @Resource
    private StudentTrainingPaperService studentTrainingPaperService;
    @Resource
    private StudentService studentService;
    @Resource
    private TestPaperExportService testPaperExportService;

    /**
     * @param semester:
     * @return R<List < TeacherPaperListDto>>
     * @author wang
     * description 获取试卷发布列表
     * date 2023/5/19 13:21
     */
    @RequestMapping("/getTestList")
    public R<Object> getPaperList(String semester) {
        try {
            String teacherNumber = AuthUserContext.get().getNumber();
            List<TeacherPaperListDto> list = new ArrayList<>();
            if (semester.isEmpty()) {
                list = teacherTestService.getPaperList(teacherNumber);
            } else {
                list = teacherTestService.getPaperListBySemester(semester, teacherNumber);
            }
            System.out.println(list);
            return R.success(list);
        } catch (Exception e) {
            log.info(String.valueOf(e));
            return R.error("出现异常，界面暂时无法显示");
        }

    }

    @RequestMapping("/resultDerivation")
    public Object resultDerivation(String testId) {
        log.info("进入了学生成绩导出系统");
        try {
            XSSFWorkbook file = teacherTestService.getStudentScore(testId);
            //保存在本地
//           FileOutputStream out = new FileOutputStream("F:/output.xlsx");
//           file.write(out);
            // 将Excel文档转换为byte数组
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            file.write(out);
            byte[] bytes = out.toByteArray();
            // 设置Content-Disposition响应头，告诉浏览器该文件应该被下载而不是展示
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=file_name.xlsx");

            // 返回ResponseEntity
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(bytes.length)
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(bytes);
        } catch (Exception e) {
            log.info(String.valueOf(e));
            return "出现异常下载失败";
        }
    }

    @RequestMapping("/deleteTestList")
    public R<String> deleteTestList(String testId) {
        String msg = teacherTestService.deleteTestList(testId);
        return R.success(msg);
    }

    /**
     * @param testPaperVo:
     * @return R<String>
     * @author wang
     * description 老师通过知识点和对应的题目数量生成一套试卷
     * date 2023/5/28 15:52
     */
    @RequestMapping("/addTestPaper")
    public R<String> addTestPaper(@RequestBody TestPaperVo testPaperVo) {
        log.info(String.valueOf(testPaperVo));
        String teacherNumber = AuthUserContext.get().getNumber();
        System.out.println("testPaperVo****************");
        System.out.println(testPaperVo);
        String msg = teacherTestService.addTestPaper(testPaperVo, teacherNumber);
        return R.success(msg);
    }

    /**
     * @param updateTestPaperTopic:
     * @return R<Object>
     * @author wang
     * description 交换同类型的题目，觉得某一道题目不合适想在同类型的里面找一个知识点一样的
     * date 2023/6/1 14:17
     */
    @RequestMapping("/UpdataTestPaper")
    public R<Object> updateTestPaper(@RequestBody UpdateTestPaperTopic updateTestPaperTopic) {
        Object trainingTopicBo = teacherTestService.updateTestPaperTopic(updateTestPaperTopic);
        return R.success(trainingTopicBo);
    }

    /**
     * @param testId:
     * @return R<String>
     * @author wang
     * description 将学生的试卷导出成word并将同一张卷子的所有人的试卷导成一个zip文件
     * date 2023/6/1 16:35
     */
    @RequestMapping("/Zip")
    public R<String> getZipUtils(String testId) throws IOException {
        String paperName = teacherTestService.getPaperName(testId);
        String zipPath = filePath + "\\" + paperName + ".zip";
        Set<String> set = new HashSet<>();
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(zipPath);

        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        ZipOutputStream zos = new ZipOutputStream(fos);
        //获取做了这张试卷的学生的学号，通过学号查找该学生的试卷结果
        set = teacherTestService.getStudentNumber(testId);
        List<String> list = new ArrayList<>(set);
        WordUtils wordUtils = new WordUtils();
        for (String studentNumber : list) {
            List<StudentPersonalTrainingResultDto> list1 = teacherTestService.getStudentPersonalTraining(testId, studentNumber);
            System.out.println(list1);
            String studentName = studentService.getStudentName(studentNumber);
            File file = null;
            try {
                file = wordUtils.getWord(list1, studentNumber, studentName, testId);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(file);
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            }
            ZipEntry zipEntry = new ZipEntry(file.getName());
            try {
                zos.putNextEntry(zipEntry);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, length);
            }
            fis.close();
            zos.closeEntry();
        }
        zos.close();
        return R.success(zipPath);
    }


    /**
     * @param paperId:
     * @param classId:
     * @param semester:
     * @return R<Object>
     * @author wang
     * description 展示学生的个人做题情况
     * date 2023/7/8 10:43
     */
    @RequestMapping("/showStudent")
    public R<Object> showStudent(String paperId, String classId, String semester) {
        List<ShowStudentDto> showStudents = teacherTestService.getStudentTest(paperId, classId, semester);
        return R.success(showStudents);
    }

    /**
     * @param paperId:
     * @return R<Object>
     * @author wang
     * description 修改试卷的饿发布状态
     * date 2023/7/8 16:05
     */
    @RequestMapping("/publishTestPaper")
    public R<Object> publishTestPaper(String paperId) {
        return R.success(teacherTestService.publishTestPaper(paperId));
    }

    /**
     * 导出学生试卷报告
     *
     * @param solvingSituationVo
     * @param response
     * @return void
     * @author Tang
     * @date 2023/10/17 14:04
     **/
    @Authentication
    @GetMapping("/export")
    public void exportStudentProblemSolvingSituation(StudentProblemSolvingSituationVo solvingSituationVo,
                                                     HttpServletResponse response) {
        testPaperExportService.exportTestPaperEachStudent(solvingSituationVo, response);
    }
}
